<!DOCTYPE html>
<html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>XiaoBot 配置中心</title>
  <!-- 引入Tailwind CSS用于快速样式开发 -->
  <script src="./assets_files/saved_resource"></script>
  <!-- 引入Font Awesome图标库 -->
  <link href="./assets_files/font-awesome.min.css" rel="stylesheet">
  
  <!-- 自定义Tailwind配置 -->
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            primary: '#4F46E5', // 主色调：深紫色（科技感）
            secondary: '#10B981', // 辅助色：绿色（成功状态）
            danger: '#EF4444', // 危险色：红色（错误状态）
            neutral: {
              100: '#F3F4F6',
              200: '#E5E7EB',
              300: '#D1D5DB',
              700: '#374151',
              800: '#1F2937',
              900: '#111827'
            }
          },
          fontFamily: {
            inter: ['Inter', 'system-ui', 'sans-serif'],
          },
          boxShadow: {
            'card': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
            'card-hover': '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
          }
        },
      }
    }
  </script>
  
  <!-- 自定义工具类 -->
  <style type="text/tailwindcss">
    @layer utilities {
      .content-auto {
        content-visibility: auto;
      }
      .group-transition {
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
      }
      .input-focus {
        @apply focus:ring-2 focus:ring-primary/50 focus:border-primary focus:outline-none;
      }
      .btn-effect {
        @apply transition-all duration-200 hover:shadow-lg active:scale-95;
      }
    }
  </style>
  
  <style>
    /* 自定义滚动条样式 */
    ::-webkit-scrollbar {
      width: 8px;
      height: 8px;
    }
    ::-webkit-scrollbar-track {
      background: #f1f5f9;
      border-radius: 4px;
    }
    ::-webkit-scrollbar-thumb {
      background: #cbd5e1;
      border-radius: 4px;
    }
    ::-webkit-scrollbar-thumb:hover {
      background: #94a3b8;
    }
    
    /* 分组内容展开收起动画 */
    .group-content {
      max-height: 2000px;
      overflow: hidden;
      transition: max-height 0.5s ease, padding 0.5s ease, opacity 0.5s ease;
      opacity: 1;
    }
    .group-content.collapsed {
      max-height: 0;
      padding-top: 0;
      padding-bottom: 0;
      opacity: 0;
    }
  </style>
<style>*, ::before, ::after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/* ! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com */*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}::after,::before{--tw-content:''}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-8{margin-bottom:2rem}.ml-auto{margin-left:auto}.mr-2{margin-right:0.5rem}.mr-3{margin-right:0.75rem}.mr-4{margin-right:1rem}.mt-1{margin-top:0.25rem}.mt-2{margin-top:0.5rem}.flex{display:flex}.grid{display:grid}.h-10{height:2.5rem}.h-5{height:1.25rem}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-5{width:1.25rem}.w-full{width:100%}.max-w-5xl{max-width:64rem}.flex-1{flex:1 1 0%}.translate-y-0{--tw-translate-y:0px;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-4{--tw-translate-y:-1rem;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-3{gap:0.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-x-3 > :not([hidden]) ~ :not([hidden]){--tw-space-x-reverse:0;margin-right:calc(0.75rem * var(--tw-space-x-reverse));margin-left:calc(0.75rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-2 > :not([hidden]) ~ :not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0.5rem * var(--tw-space-y-reverse))}.space-y-6 > :not([hidden]) ~ :not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.rounded{border-radius:0.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:0.5rem}.rounded-xl{border-radius:0.75rem}.rounded-t-lg{border-top-left-radius:0.5rem;border-top-right-radius:0.5rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-neutral-200{--tw-border-opacity:1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-neutral-300{--tw-border-opacity:1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-danger{--tw-border-opacity:1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.bg-neutral-100{--tw-bg-opacity:1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-neutral-50{--tw-bg-opacity:1;background-color:rgb(250 250 250 / var(--tw-bg-opacity, 1))}.bg-primary{--tw-bg-opacity:1;background-color:rgb(79 70 229 / var(--tw-bg-opacity, 1))}.bg-primary\/10{background-color:rgb(79 70 229 / 0.1)}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-danger\/10{background-color:rgb(239 68 68 / 0.1)}.bg-gradient-to-r{background-image:linear-gradient(to right, var(--tw-gradient-stops))}.from-primary{--tw-gradient-from:#4F46E5 var(--tw-gradient-from-position);--tw-gradient-to:rgb(79 70 229 / 0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to)}.to-primary\/80{--tw-gradient-to:rgb(79 70 229 / 0.8) var(--tw-gradient-to-position)}.p-3{padding:0.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-4{padding-left:1rem;padding-right:1rem}.px-8{padding-left:2rem;padding-right:2rem}.py-2{padding-top:0.5rem;padding-bottom:0.5rem}.py-2\.5{padding-top:0.625rem;padding-bottom:0.625rem}.py-3{padding-top:0.75rem;padding-bottom:0.75rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pt-1{padding-top:0.25rem}.pt-2{padding-top:0.5rem}.pt-4{padding-top:1rem}.font-inter{font-family:Inter, system-ui, sans-serif}.text-\[clamp\(1\.5rem\2c 3vw\2c 2\.2rem\)\]{font-size:clamp(1.5rem,3vw,2.2rem)}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:0.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.text-neutral-500{--tw-text-opacity:1;color:rgb(115 115 115 / var(--tw-text-opacity, 1))}.text-neutral-600{--tw-text-opacity:1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.text-neutral-700{--tw-text-opacity:1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-neutral-800{--tw-text-opacity:1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-primary{--tw-text-opacity:1;color:rgb(79 70 229 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/90{color:rgb(255 255 255 / 0.9)}.text-danger{--tw-text-opacity:1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow-card{--tw-shadow:0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms}.duration-200{transition-duration:200ms}.duration-300{transition-duration:300ms}.group-transition {
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
      }.input-focus:focus{--tw-border-opacity:1;border-color:rgb(79 70 229 / var(--tw-border-opacity, 1));outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);--tw-ring-color:rgb(79 70 229 / 0.5)}.btn-effect{transition-property:all;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:200ms}.btn-effect:hover{--tw-shadow:0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}.btn-effect:active{--tw-scale-x:.95;--tw-scale-y:.95;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
    .hover\:bg-primary\/90:hover{background-color:rgb(79 70 229 / 0.9)}
    .hover\:shadow-card-hover:hover{--tw-shadow:0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}
    .focus\:border-primary:focus{--tw-border-opacity:1;border-color:rgb(79 70 229 / var(--tw-border-opacity, 1))}
    .focus\:ring:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)}
    .focus\:ring-4:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)}
    .focus\:ring-primary\/20:focus{--tw-ring-color:rgb(79 70 229 / 0.2)}
    .focus\:ring-primary\/30:focus{--tw-ring-color:rgb(79 70 229 / 0.3)}
    .focus\:ring-primary\/50:focus{--tw-ring-color:rgb(79 70 229 / 0.5)}
    @media (min-width: 640px){.sm\:flex-row{flex-direction:row}}
    @media (min-width: 768px){.md\:col-span-2{grid-column:span 2 / span 2}.md\:mx-8{margin-left:2rem;margin-right:2rem}.md\:grid-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3, minmax(0, 1fr))}.md\:p-5{padding:1.25rem}.md\:p-8{padding:2rem}.md\:px-8{padding-left:2rem;padding-right:2rem}.md\:pt-0{padding-top:0px}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}}
  </style><style>*, ::before, ::after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/* ! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com */*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}::after,::before{--tw-content:''}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-8{margin-bottom:2rem}.ml-auto{margin-left:auto}.mr-2{margin-right:0.5rem}.mr-3{margin-right:0.75rem}.mr-4{margin-right:1rem}.mt-1{margin-top:0.25rem}.mt-2{margin-top:0.5rem}.flex{display:flex}.grid{display:grid}.h-10{height:2.5rem}.h-5{height:1.25rem}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-5{width:1.25rem}.w-full{width:100%}.max-w-5xl{max-width:64rem}.flex-1{flex:1 1 0%}.-translate-y-4{--tw-translate-y:-1rem;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0{--tw-translate-y:0px;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-3{gap:0.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-x-3 > :not([hidden]) ~ :not([hidden]){--tw-space-x-reverse:0;margin-right:calc(0.75rem * var(--tw-space-x-reverse));margin-left:calc(0.75rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-2 > :not([hidden]) ~ :not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0.5rem * var(--tw-space-y-reverse))}.space-y-6 > :not([hidden]) ~ :not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.rounded{border-radius:0.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:0.5rem}.rounded-xl{border-radius:0.75rem}.rounded-t-lg{border-top-left-radius:0.5rem;border-top-right-radius:0.5rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-danger{--tw-border-opacity:1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.border-neutral-200{--tw-border-opacity:1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-neutral-300{--tw-border-opacity:1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.bg-danger\/10{background-color:rgb(239 68 68 / 0.1)}.bg-neutral-100{--tw-bg-opacity:1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-neutral-50{--tw-bg-opacity:1;background-color:rgb(250 250 250 / var(--tw-bg-opacity, 1))}.bg-primary{--tw-bg-opacity:1;background-color:rgb(79 70 229 / var(--tw-bg-opacity, 1))}.bg-primary\/10{background-color:rgb(79 70 229 / 0.1)}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-gradient-to-r{background-image:linear-gradient(to right, var(--tw-gradient-stops))}.from-primary{--tw-gradient-from:#4F46E5 var(--tw-gradient-from-position);--tw-gradient-to:rgb(79 70 229 / 0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to)}.to-primary\/80{--tw-gradient-to:rgb(79 70 229 / 0.8) var(--tw-gradient-to-position)}.p-3{padding:0.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-4{padding-left:1rem;padding-right:1rem}.px-8{padding-left:2rem;padding-right:2rem}.py-2{padding-top:0.5rem;padding-bottom:0.5rem}.py-2\.5{padding-top:0.625rem;padding-bottom:0.625rem}.py-3{padding-top:0.75rem;padding-bottom:0.75rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pt-1{padding-top:0.25rem}.pt-2{padding-top:0.5rem}.pt-4{padding-top:1rem}.font-inter{font-family:Inter, system-ui, sans-serif}.text-\[clamp\(1\.5rem\2c 3vw\2c 2\.2rem\)\]{font-size:clamp(1.5rem,3vw,2.2rem)}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:0.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.text-danger{--tw-text-opacity:1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-neutral-500{--tw-text-opacity:1;color:rgb(115 115 115 / var(--tw-text-opacity, 1))}.text-neutral-600{--tw-text-opacity:1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.text-neutral-700{--tw-text-opacity:1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-neutral-800{--tw-text-opacity:1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-primary{--tw-text-opacity:1;color:rgb(79 70 229 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/90{color:rgb(255 255 255 / 0.9)}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow-card{--tw-shadow:0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:150ms}.duration-200{transition-duration:200ms}.duration-300{transition-duration:300ms}.group-transition {
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
      }.input-focus:focus{--tw-border-opacity:1;border-color:rgb(79 70 229 / var(--tw-border-opacity, 1));outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);--tw-ring-color:rgb(79 70 229 / 0.5)}.btn-effect{transition-property:all;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);transition-duration:200ms}.btn-effect:hover{--tw-shadow:0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}.btn-effect:active{--tw-scale-x:.95;--tw-scale-y:.95;transform:translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
    .hover\:bg-primary\/90:hover{background-color:rgb(79 70 229 / 0.9)}
    .hover\:shadow-card-hover:hover{--tw-shadow:0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}
    .focus\:border-primary:focus{--tw-border-opacity:1;border-color:rgb(79 70 229 / var(--tw-border-opacity, 1))}
    .focus\:ring:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)}
    .focus\:ring-4:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)}
    .focus\:ring-primary\/20:focus{--tw-ring-color:rgb(79 70 229 / 0.2)}
    .focus\:ring-primary\/30:focus{--tw-ring-color:rgb(79 70 229 / 0.3)}
    .focus\:ring-primary\/50:focus{--tw-ring-color:rgb(79 70 229 / 0.5)}
    @media (min-width: 640px){.sm\:flex-row{flex-direction:row}}
    @media (min-width: 768px){.md\:col-span-2{grid-column:span 2 / span 2}.md\:mx-8{margin-left:2rem;margin-right:2rem}.md\:grid-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3, minmax(0, 1fr))}.md\:p-5{padding:1.25rem}.md\:p-8{padding:2rem}.md\:px-8{padding-left:2rem;padding-right:2rem}.md\:pt-0{padding-top:0px}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}}
  </style></head>
<body class="font-inter bg-neutral-100 min-h-screen py-8 px-4 md:px-8">
  <div class="max-w-5xl mx-auto bg-white rounded-xl shadow-card overflow-hidden">
    <!-- 页面标题 -->
    <div class="bg-gradient-to-r from-primary to-primary/80 text-white p-6 md:p-8">
      <h1 class="text-[clamp(1.5rem,3vw,2.2rem)] font-bold flex items-center">
        <i class="fa fa-cogs mr-3 text-xl"></i>
        XiaoBot 配置中心
      </h1>
      <p class="mt-2 text-white/90">轻松配置您的XiaoBot各项参数，打造个性化智能体验</p>
    </div>
    
    <!-- 表单内容 -->
    <form id="config-form" class="p-6 md:p-8 space-y-6">
      <!-- 1. 帐号配置组 - 默认展开 -->
      <div class="config-group bg-white rounded-lg shadow-card group-transition hover:shadow-card-hover border border-neutral-200">
        <div class="group-header bg-neutral-50 p-4 md:p-5 rounded-t-lg cursor-pointer flex justify-between items-center border-b border-neutral-200" onclick="toggleGroup(&#39;accountGroup&#39;)">
          <div class="flex items-center">
            <div class="w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center text-primary mr-4">
              <i class="fa fa-user-circle-o text-lg"></i>
            </div>
            <h2 class="text-lg md:text-xl font-semibold text-neutral-800">【帐号配置】</h2>
          </div>
          <div class="group-toggle text-neutral-600 transition-transform duration-300" id="accountGroupToggle">
            <i class="fa fa-chevron-down"></i>
          </div>
        </div>
        
        <div class="group-content p-4 md:p-5" id="accountGroupContent">
          <div class="space-y-6">
            <!-- 小米账号 -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="account" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-user mr-2 text-primary"></i>小米账号
              </label>
              <div class="md:col-span-2">
                <input type="text" id="account" name="account" required="" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="请输入您的小米账号">
                <p class="mt-1 text-sm text-neutral-500">用于登录小米生态系统的账号</p>
              </div>
            </div>
            
            <!-- 小米密码 -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="password" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-lock mr-2 text-primary"></i>小米密码
              </label>
              <div class="md:col-span-2 space-y-2">
                <input type="password" id="password" name="password" required="" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="请输入您的小米密码">

                <!-- 设备选择区域 -->
                <div class="device-selection flex flex-col sm:flex-row gap-3 pt-1">
                  <button type="button" id="fetch-hardware" onclick="fetchHardwareInfo()" disabled="" class="px-4 py-2 rounded-lg bg-primary text-white font-medium btn-effect flex items-center justify-center">
                    <i class="fa fa-search mr-2"></i>获取音箱信息
                  </button>
                  <select id="device-select" name="device-select" disabled="" class="flex-1 px-4 py-2 rounded-lg border border-neutral-300 bg-white text-neutral-700 focus:border-primary focus:ring focus:ring-primary/20 transition-all duration-200">
                    <option value="">请选择设备</option>
                  </select>
                </div>
              </div>
            </div>
            
            <!-- 硬件类型 -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="hardware" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-microchip mr-2 text-primary"></i>硬件类型
              </label>
              <div class="md:col-span-2">
                <input type="text" id="hardware" name="hardware" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="请选择设备后自动填写">
                <p class="mt-1 text-sm text-neutral-500">例如：LX04、L05B等音箱硬件型号</p>
              </div>
            </div>
            
            <!-- MiDID -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="mi-did" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-id-card-o mr-2 text-primary"></i>MiDID
              </label>
              <div class="md:col-span-2">
                <input type="text" id="mi-did" name="mi_did" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="请选择设备后自动填写">
                <p class="mt-1 text-sm text-neutral-500">小米音箱的唯一设备标识</p>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 2. 大模型AI配置组 - 默认收起 -->
      <div class="config-group bg-white rounded-lg shadow-card group-transition hover:shadow-card-hover border border-neutral-200">
        <div class="group-header bg-neutral-50 p-4 md:p-5 rounded-t-lg cursor-pointer flex justify-between items-center border-b border-neutral-200" onclick="toggleGroup(&#39;aiGroup&#39;)">
          <div class="flex items-center">
            <div class="w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center text-primary mr-4">
              <i class="fa fa-robot text-lg"></i>
            </div>
            <h2 class="text-lg md:text-xl font-semibold text-neutral-800">【大模型AI配置】</h2>
          </div>
          <div class="group-toggle text-neutral-600 transition-transform duration-300 collapsed" id="aiGroupToggle">
            <i class="fa fa-chevron-down"></i>
          </div>
        </div>
        
        <div class="group-content p-4 md:p-5 collapsed" id="aiGroupContent">
          <div class="space-y-6">
            <!-- OpenAI Key -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="openai-key" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-key mr-2 text-primary"></i>API-Key
              </label>
              <div class="md:col-span-2">
                <input type="text" id="openai-key" name="openai_key" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="OpenAI API密钥">
                <p class="mt-1 text-sm text-neutral-500">用于访问大模型API的密钥</p>
              </div>
            </div>
            
            <!-- OpenAI Base Url -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="openai-backend" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-link mr-2 text-primary"></i>API-Url
              </label>
              <div class="md:col-span-2">
                <input type="text" id="openai-backend" name="openai_backend" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="不用带上&#39;/chat/completions&#39;后缀">
                <p class="mt-1 text-sm text-neutral-500">大模型API的基础地址</p>
              </div>
            </div>
            
            <!-- AI机器人/模型 -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="bot" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-cog mr-2 text-primary"></i>AI模型
              </label>
              <div class="md:col-span-2">
                <input type="text" id="bot" name="bot" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="例如：gpt-3.5-turbo、gpt-4">
                <p class="mt-1 text-sm text-neutral-500">指定使用的AI模型名称</p>
              </div>
            </div>
            
            <!-- GPT选项 -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="gpt-options" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-sliders mr-2 text-primary"></i>GPT选项
              </label>
              <div class="md:col-span-2">
                <textarea id="gpt-options" name="gpt_options" rows="4" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="例如: {&quot;temperature&quot;: 0.7, &quot;max_tokens&quot;: 1000}"></textarea>
                <p class="mt-1 text-sm text-neutral-500">JSON格式的GPT参数配置</p>
              </div>
            </div>
            
            <!-- AI提示词 -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="prompt" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-comment mr-2 text-primary"></i>AI提示词
              </label>
              <div class="md:col-span-2">
                <textarea id="prompt" name="prompt" rows="4" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="请输入AI的系统提示词"></textarea>
                <p class="mt-1 text-sm text-neutral-500">定义AI的行为模式和角色设定</p>
              </div>
            </div>
            
            <!-- 激活关键词 -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="keyword" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-bell mr-2 text-primary"></i>激活关键词
              </label>
              <div class="md:col-span-2">
                <input type="text" id="keyword" name="keyword" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="多个关键词之间用逗号&#39;,&#39;分隔">
                <p class="mt-1 text-sm text-neutral-500">触发AI响应的关键词</p>
              </div>
            </div>
            
            <!-- 小爱思考说词 -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="thinking" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-lightbulb-o mr-2 text-primary"></i>思考说词
              </label>
              <div class="md:col-span-2">
                <input type="text" id="thinking" name="thinking" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="多个关键词之间用逗号&#39;,&#39;分隔">
                <p class="mt-1 text-sm text-neutral-500">小爱思考时的提示语</p>
              </div>
            </div>
            
            <!-- 更新bot人设指令 -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="change-prompt-keyword" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-refresh mr-2 text-primary"></i>更新人设指令
              </label>
              <div class="md:col-span-2">
                <input type="text" id="change-prompt-keyword" name="change_prompt_keyword" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="多个指令之间用逗号&#39;,&#39;分隔">
                <p class="mt-1 text-sm text-neutral-500">用于更新AI人设的指令词</p>
              </div>
            </div>
            
            <!-- 开始连续对话指令 -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="start-conversation" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-play-circle mr-2 text-primary"></i>开始连续对话
              </label>
              <div class="md:col-span-2">
                <input type="text" id="start-conversation" name="start_conversation" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="例如：开启连续对话">
                <p class="mt-1 text-sm text-neutral-500">触发连续对话模式的指令</p>
              </div>
            </div>
            
            <!-- 结束连续对话指令 -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="end-conversation" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-stop-circle mr-2 text-primary"></i>结束连续对话
              </label>
              <div class="md:col-span-2">
                <input type="text" id="end-conversation" name="end_conversation" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="例如：结束连续对话">
                <p class="mt-1 text-sm text-neutral-500">退出连续对话模式的指令</p>
              </div>
            </div>
            
          </div>
        </div>
      </div>

      <!-- 3. 系统参数组 - 默认展开 -->
      <div class="config-group bg-white rounded-lg shadow-card group-transition hover:shadow-card-hover border border-neutral-200">
        <div class="group-header bg-neutral-50 p-4 md:p-5 rounded-t-lg cursor-pointer flex justify-between items-center border-b border-neutral-200" onclick="toggleGroup(&#39;systemGroup&#39;)">
          <div class="flex items-center">
            <div class="w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center text-primary mr-4">
              <i class="fa fa-cog text-lg"></i>
            </div>
            <h2 class="text-lg md:text-xl font-semibold text-neutral-800">【系统设置】</h2>
          </div>
          <div class="group-toggle text-neutral-600 transition-transform duration-300" id="systemGroupToggle">
            <i class="fa fa-chevron-down"></i>
          </div>
        </div>
        
        <div class="group-content p-4 md:p-5" id="systemGroupContent">
          <div class="space-y-6">
            <!-- 复选框组 -->
            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
              <!-- 静音小爱 -->
              <div class="checkbox-group flex items-center space-x-3 p-3 bg-neutral-50 rounded-lg border border-neutral-200">
                <input type="checkbox" id="mute-xiaoai" name="mute_xiaoai" class="w-5 h-5 text-primary focus:ring-primary/50 border-neutral-300 rounded transition-all duration-200">
                <label for="mute-xiaoai" class="text-neutral-700 font-medium cursor-pointer flex items-center">
                  <i class="fa fa-volume-off mr-2 text-primary"></i>静音小爱
                </label>
                <span class="ml-auto text-sm text-neutral-500">（快速停掉小爱回答）</span>
              </div>
              
              <!-- 采用命令方式 -->
              <div class="checkbox-group flex items-center space-x-3 p-3 bg-neutral-50 rounded-lg border border-neutral-200">
                <input type="checkbox" id="use-command" name="use_command" class="w-5 h-5 text-primary focus:ring-primary/50 border-neutral-300 rounded transition-all duration-200">
                <label for="use-command" class="text-neutral-700 font-medium cursor-pointer flex items-center">
                  <i class="fa fa-terminal mr-2 text-primary"></i>采用命令方式
                </label>
                <span class="ml-auto text-sm text-neutral-500">（LX04/L05B/L05C等适用）</span>
              </div>
              
              <!-- 支持流式响应 -->
              <div class="checkbox-group flex items-center space-x-3 p-3 bg-neutral-50 rounded-lg border border-neutral-200">
                <input type="checkbox" id="stream" name="stream" class="w-5 h-5 text-primary focus:ring-primary/50 border-neutral-300 rounded transition-all duration-200">
                <label for="stream" class="text-neutral-700 font-medium cursor-pointer flex items-center">
                  <i class="fa fa-stream mr-2 text-primary"></i>启用大模型流式响应
                </label>
                <span class="ml-auto text-sm text-neutral-500"></span>
              </div>
              
              <!-- 详细日志 -->
              <div class="checkbox-group flex items-center space-x-3 p-3 bg-neutral-50 rounded-lg border border-neutral-200">
                <input type="checkbox" id="verbose" name="verbose" class="w-5 h-5 text-primary focus:ring-primary/50 border-neutral-300 rounded transition-all duration-200">
                <label for="verbose" class="text-neutral-700 font-medium cursor-pointer flex items-center">
                  <i class="fa fa-file-text-o mr-2 text-primary"></i>详细日志
                </label>
                <span class="ml-auto text-sm text-neutral-500">（调试时启用）</span>
              </div>
            </div>
            
            <!-- AI-proxy 代理 -->
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
              <label for="proxy" class="text-neutral-700 font-medium pt-2 md:pt-0">
                <i class="fa fa-random mr-2 text-primary"></i>AI代理
              </label>
              <div class="md:col-span-2">
                <input type="text" id="proxy" name="proxy" class="w-full px-4 py-2.5 rounded-lg border border-neutral-300 input-focus transition-all duration-200 bg-white" placeholder="例如：http://127.0.0.1:7890">
                <p class="mt-1 text-sm text-neutral-500">访问AI服务的代理地址（可选）</p>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 提交按钮 -->
      <div class="flex justify-center pt-4">
        <input type="submit" value="保存配置" class="px-8 py-3 bg-primary text-white font-semibold rounded-lg btn-effect shadow-lg hover:bg-primary/90 focus:ring-4 focus:ring-primary/30">
      </div>
    </form>
    
    <!-- 消息提示框 -->
    <div id="message" class="mx-6 md:mx-8 mb-8 p-4 rounded-lg transform transition-all duration-300 bg-danger/10 border border-danger text-danger -translate-y-4 opacity-0" style="display: none;">
      <span id="message-text" class="font-medium">加载配置失败，请刷新页面重试</span>
    </div>
  </div>
  
  <script>
    // 分组展开收起控制函数
    function toggleGroup(groupId) {
      const content = document.getElementById(`${groupId}Content`);
      const toggleIcon = document.getElementById(`${groupId}Toggle`);
      
      // 切换折叠状态
      content.classList.toggle('collapsed');
      toggleIcon.classList.toggle('collapsed');
      
      // 旋转图标
      if (toggleIcon.classList.contains('collapsed')) {
        toggleIcon.style.transform = 'rotate(-90deg)';
      } else {
        toggleIcon.style.transform = 'rotate(0)';
      }
    }

    // 页面加载时获取配置并填充表单
    async function loadConfig() {
        try {
            const response = await fetch('/get-config');
            if (response.ok) {
                const config = await response.json();
                if (Object.keys(config).length > 0) {
                    populateForm(config);
                }
            }
        } catch (error) {
            console.error('加载配置失败:', error);
            showMessage('加载配置失败，请刷新页面重试', 'error');
        }
    }

    // 填充表单数据
    function populateForm(config) {
        document.getElementById('account').value = config.account || '';
        document.getElementById('password').value = config.password || '';
        document.getElementById('hardware').value = config.hardware || '';
        document.getElementById('mi-did').value = config.mi_did || '';
        document.getElementById('openai-key').value = config.openai_key || '';
        document.getElementById('openai-backend').value = config.openai_backend || '';
        document.getElementById('bot').value = config.bot || '';
        
        // 处理GPT选项的JSON显示
        if (config.gpt_options) {
            document.getElementById('gpt-options').value = JSON.stringify(config.gpt_options, null, 2) || '';
        }
        
        // 处理关键词数组
        document.getElementById('keyword').value = (config.keyword || []).join(', ') || '';
        document.getElementById('thinking').value = (config.thinking || []).join(', ') || '';
        document.getElementById('prompt').value = config.prompt || '';
        document.getElementById('change-prompt-keyword').value = (config.change_prompt_keyword || []).join(', ') || '';
        document.getElementById('start-conversation').value = (config.start_conversation || []).join(', ') || '';
        document.getElementById('end-conversation').value = (config.end_conversation || []).join(', ') || '';
        
        // 处理复选框
        document.getElementById('mute-xiaoai').checked = config.mute_xiaoai || false;
        document.getElementById('use-command').checked = config.use_command || false;
        document.getElementById('verbose').checked = config.verbose || false;
        document.getElementById('stream').checked = config.stream || false;
        
        document.getElementById('proxy').value = config.proxy || '';

        // 页面加载时初始化按钮状态
        checkCredentials();
    }

    // 检查账号和密码是否都已填写，控制按钮状态
    function checkCredentials() {
      const account = document.getElementById('account').value.trim();
      const password = document.getElementById('password').value.trim();
      const hasCredentials = account !== '' && password !== '';
      const fetchBtn = document.getElementById('fetch-hardware');
      
      // 控制按钮的禁用状态和样式
      if (hasCredentials) {
        fetchBtn.disabled = false;
        fetchBtn.classList.remove('bg-neutral-400');
        fetchBtn.classList.add('bg-primary');
      } else {
        fetchBtn.disabled = true;
        fetchBtn.classList.remove('bg-primary');
        fetchBtn.classList.add('bg-neutral-400');
      }
    }

    // 设备选择变化时更新硬件信息
    function onDeviceSelectChange() {
      const select = document.getElementById('device-select');
      const selectedOption = select.options[select.selectedIndex];
      
      if (selectedOption) {
        const hardware = selectedOption.getAttribute('data-hardware');
        const midid = selectedOption.getAttribute('data-midid');
        
        document.getElementById('hardware').value = hardware;
        document.getElementById('mi-did').value = midid;
        
        // 添加输入框动画效果
        const hardwareInput = document.getElementById('hardware');
        const mididInput = document.getElementById('mi-did');
        
        hardwareInput.classList.add('ring-2', 'ring-secondary/50');
        mididInput.classList.add('ring-2', 'ring-secondary/50');
        
        setTimeout(() => {
          hardwareInput.classList.remove('ring-2', 'ring-secondary/50');
          mididInput.classList.remove('ring-2', 'ring-secondary/50');
        }, 1000);
      }
    }

    // 获取硬件信息
    async function fetchHardwareInfo() {
      try {
        const account = document.getElementById('account').value.trim();
        const password = document.getElementById('password').value.trim();
        const fetchBtn = document.getElementById('fetch-hardware');
        
        // 按钮加载状态
        fetchBtn.disabled = true;
        fetchBtn.innerHTML = '<i class="fa fa-spinner fa-spin mr-2"></i>获取中...';
        
        const response = await fetch('/get-devices', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ account, password })
        });
        
        // 恢复按钮状态
        fetchBtn.innerHTML = '<i class="fa fa-search mr-2"></i>获取音箱信息';
        checkCredentials();
        
        if (response.ok) {
          const devices = await response.json();
          const select = document.getElementById('device-select');
          
          // 清空现有选项
          select.innerHTML = '<option value="">请选择设备</option>';
          
          if (devices && devices.length > 0) {
            // 添加设备选项
            devices.forEach(device => {
              const option = document.createElement('option');
              option.value = device.midid;
              option.textContent = device.name;
              option.setAttribute('data-hardware', device.hardware);
              option.setAttribute('data-midid', device.midid);
              select.appendChild(option);
            });
            
            // 启用下拉框并添加事件监听
            select.disabled = false;
            select.addEventListener('change', onDeviceSelectChange);
            
            // 添加下拉框动画效果
            select.classList.add('ring-2', 'ring-secondary/50');
            setTimeout(() => {
              select.classList.remove('ring-2', 'ring-secondary/50');
            }, 1000);
            
            // 默认选中第一项并填充信息
            if (devices.length > 0) {
              select.selectedIndex = 1;
              onDeviceSelectChange();
            }
            
            showMessage('成功获取到' + devices.length + '个设备', 'success');
          } else {
            select.disabled = true;
            showMessage('未获取到任何设备', 'error');
          }
        } else {
          const error = await response.text();
          console.error('获取硬件信息失败:', error);
          showMessage('获取硬件信息失败: ' + error, 'error');
        }
      } catch (error) {
        const fetchBtn = document.getElementById('fetch-hardware');
        fetchBtn.innerHTML = '<i class="fa fa-search mr-2"></i>获取音箱信息';
        checkCredentials();
        
        console.error('获取硬件信息失败:', error);
        showMessage('获取硬件信息失败: ' + error.message, 'error');
      }
    }

    // 显示消息提示
    function showMessage(text, type) {
      const messageElement = document.getElementById('message');
      const messageText = document.getElementById('message-text');
      
      // 设置消息内容和样式
      messageText.textContent = text;
      messageElement.style.display = 'block';
      
      // 根据类型设置样式
      if (type === 'success') {
        messageElement.className = 'mx-6 md:mx-8 mb-8 p-4 rounded-lg transform transition-all duration-300 bg-secondary/10 border border-secondary text-secondary';
      } else if (type === 'error') {
        messageElement.className = 'mx-6 md:mx-8 mb-8 p-4 rounded-lg transform transition-all duration-300 bg-danger/10 border border-danger text-danger';
      }
      
      // 显示动画
      setTimeout(() => {
        messageElement.classList.add('translate-y-0', 'opacity-100');
        messageElement.classList.remove('-translate-y-4', 'opacity-0');
      }, 10);
      
      // 5秒后自动隐藏
      setTimeout(() => {
        messageElement.classList.add('-translate-y-4', 'opacity-0');
        messageElement.classList.remove('translate-y-0', 'opacity-100');
        
        setTimeout(() => {
          messageElement.style.display = 'none';
        }, 300);
      }, 5000);
    }

    // 页面加载完成后执行
    window.addEventListener('load', () => {
      loadConfig();
      
      // 监听账号和密码输入变化
      document.getElementById('account').addEventListener('input', checkCredentials);
      document.getElementById('password').addEventListener('input', checkCredentials);
      
      // 表单提交处理
      const form = document.getElementById('config-form');
      form.addEventListener('submit', async function(event) {
        event.preventDefault();
        
        // 验证账号和密码
        const account = document.getElementById('account').value.trim();
        const password = document.getElementById('password').value.trim();
        if (!account || !password) {
          showMessage('账号和密码不能为空!', 'error');
          return;
        }
        
        // 处理GPT选项的JSON解析
        let gptOptions;
        try {
          const gptOptionsStr = document.getElementById('gpt-options').value.trim() || '{}';
          gptOptions = JSON.parse(gptOptionsStr);
        } catch (e) {
          showMessage('GPT选项格式错误，请输入合法的JSON', 'error');
          return;
        }
        
        // 收集表单数据
        const config = {
          hardware: document.getElementById('hardware').value,
          account: account,
          password: password,
          openai_key: document.getElementById('openai-key').value,
          openai_backend: document.getElementById('openai-backend').value,
          proxy: document.getElementById('proxy').value,
          mi_did: document.getElementById('mi-did').value,
          keyword: document.getElementById('keyword').value.split(',').map(k => k.trim()).filter(k => k),
          thinking: document.getElementById('thinking').value.split(',').map(k => k.trim()).filter(k => k),
          change_prompt_keyword: document.getElementById('change-prompt-keyword').value.split(',').map(k => k.trim()).filter(k => k),
          prompt: document.getElementById('prompt').value,
          mute_xiaoai: document.getElementById('mute-xiaoai').checked,
          bot: document.getElementById('bot').value,
          use_command: document.getElementById('use-command').checked,
          verbose: document.getElementById('verbose').checked,
          start_conversation: document.getElementById('start-conversation').value.split(',').map(k => k.trim()).filter(k => k),
          end_conversation: document.getElementById('end-conversation').value.split(',').map(k => k.trim()).filter(k => k),
          stream: document.getElementById('stream').checked,
          gpt_options: gptOptions,
        };
        
        try {
          const submitBtn = form.querySelector('input[type="submit"]');
          // 按钮加载状态
          submitBtn.disabled = true;
          submitBtn.value = '保存中...';
          submitBtn.classList.add('bg-primary/70');
          
          // 发送POST请求到后端接口
          const response = await fetch('/submit-config', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify(config)
          });
          
          const result = await response.json();
          
          // 恢复按钮状态
          submitBtn.disabled = false;
          submitBtn.value = '保存配置';
          submitBtn.classList.remove('bg-primary/70');
          
          if (response.ok) {
            showMessage(result.message || '配置提交成功!', 'success');
            // 表单提交成功后的动画效果
            form.classList.add('opacity-50');
            setTimeout(() => {
              form.classList.remove('opacity-50');
              window.location.href = "/";
            }, 1000);
          } else {
            showMessage(result.message || '提交失败，请重试', 'error');
          }
        } catch (networkError) {
          const submitBtn = form.querySelector('input[type="submit"]');
          // 恢复按钮状态
          submitBtn.disabled = false;
          submitBtn.value = '保存配置';
          submitBtn.classList.remove('bg-primary/70');
          
          showMessage('网络请求失败，请检查服务是否运行', 'error');
          console.error('网络错误:', networkError);
        }
      });
    });
  </script>


</body></html>